﻿using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using RAP.Framework.Libary.DomTemplateBuilder.Configuration;
using RAP.Framework.Libary.Utils;
using RAP.Web.Libary.Common;
using RAP.Web.Libary.Service.Attributes;

namespace RAP.Web.Libary.Service
{
  /// <summary>
  /// 扩展
  /// </summary>
  public static class Extensions
  {
    /// <summary>
    /// 自动注册当前程序集下所有IAPIService接口的服务对象
    /// </summary>
    /// <param name="services"></param>
    public static void InitServices<TService>(this IServiceCollection services)
    {
      //自动将所有实现了IAPIService接口的对象注册到IOC容器
      var serviceInterfaceType = typeof(TService);
      AppDomain.CurrentDomain.GetAssemblies()
                  .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(serviceInterfaceType))).All((type =>
      {
        if (type.IsClass
            && !type.IsAbstract
            && !type.IsInterface
            && type.GetInterface(serviceInterfaceType.Name) != null)
        {
          var attrs = type.GetCustomAttributes<ServiceScopeAttribute>();
          if (attrs?.Count() > 0)
          {
            foreach (var attr in attrs)
            {
              var scopeType = ServiceScopeTypes.Scoped;
              Type serviceType = null;
              if (attr != null)
              {
                scopeType = attr.ScopeType;
                serviceType = attr.ServiceType;
              }
              switch (scopeType)
              {
                case ServiceScopeTypes.Scoped:
                  if (serviceType != null)
                  {
                    services.AddScoped(serviceType, type);
                  }
                  else
                  {
                    services.AddScoped(type);
                  }
                  break;

                case ServiceScopeTypes.Transient:
                  if (serviceType != null)
                  {
                    services.AddTransient(serviceType, type);
                  }
                  else
                  {
                    services.AddTransient(type);
                  }
                  break;

                case ServiceScopeTypes.Singleton:
                  if (serviceType != null)
                  {
                    services.AddSingleton(serviceType, type);
                  }
                  else
                  {
                    services.AddSingleton(type);
                  }
                  break;
              }
            }
          }
          else
          {
            services.AddScoped(type);
          }
        }
        return true;
      }));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="attrs"></param>
    /// <returns></returns>
    public static string ModuleName(this AttributeCollection attrs)
    {
      return attrs.ToString(FieldConsts.LOG_MODULE_NAME_FIELD);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="attrs"></param>
    /// <returns></returns>
    public static string ModuleParams(this AttributeCollection attrs)
    {
      return attrs.ToString(FieldConsts.LOG_MODULE_PARAMS_FIELD);
    }
  }
}
